#include "ProxyConnection.h"
#include "../Stringops/StringOps.h"
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#include <iostream>
#include "../Errors/errors.h"
using namespace std;

#define READ_BLOCK_SIZE 256

bool is_ip(std::string _host) {
	std::vector<std::string> parts = split(_host, '.');
	for(unsigned int i = 0; i < parts.size(); i++)
		if(!is_numeric(parts[i]))
			return false;
	return true;
}

sockaddr_in ProxyConnection::host_to_addr(std::string _host, unsigned short _port) {
	struct sockaddr_in output;
	struct hostent * he;

	output.sin_family = AF_INET;
	output.sin_port = htons(_port);

	if(is_ip(_host)) {
		// Get host by addr
		output.sin_addr.s_addr = inet_addr(_host.c_str());
	} else {
		// Get host by name
		he = gethostbyname(_host.c_str());
		if(he == 0) {
			std::string err_msg = "";
			if(errno == HOST_NOT_FOUND) {
				err_msg = "Host not found.";
			}
			else if(errno == NO_ADDRESS) {
				err_msg = "No address associated with hostname.";
			}
			else {
				err_msg = "Could not resolve hostname.";
			}
			printf("Error: %s\n", err_msg.c_str());
			output.sin_addr.s_addr = null;
			return output;
		}
		output.sin_addr.s_addr = inet_addr(he->h_addr);
	}

	return output;
}

void ProxyConnection::close_connection() {
	close(sock);
}

std::string ProxyConnection::send_url(std::string msg) {
	result = send(sock, msg.c_str(), msg.size(), 0);
	if(result < 0) {
		auto_set_error("send_url");
		return "";
	}
	std::string response;
	char c;
	int _res;
	while((_res = recv(sock, &c, 1, 0)) == 1) {
		if(c != 0) {
			response.push_back(c);
		}
		else
			break;
	}
	if(_res < 0) {
		result = _res;
		auto_set_error("send_url");
		return "";
	}
	return response;
}
